{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "ename": "ModuleNotFoundError",
     "evalue": "No module named 'sobol_seq'",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mModuleNotFoundError\u001b[0m                       Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-4-75792c49b3af>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m     12\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mtime\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     13\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 14\u001b[1;33m \u001b[1;32mfrom\u001b[0m \u001b[0mcore\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0macquisitions\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mEI\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mUCB\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mUEI\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m     15\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mcore\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0macquisitions\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mNESRejectionSamplingGrid\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mNESExpProp\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     16\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mcore\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mutil\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mobjectives\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mmisc\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mrun_experiments\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0meval_experiments\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32m~\\PhD\\Code\\Paper\\2019_NeurIPS\\core\\acquisitions\\__init__.py\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m      3\u001b[0m \u001b[1;31m# All rights reserved.\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      4\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 5\u001b[1;33m \u001b[1;32mfrom\u001b[0m \u001b[1;33m.\u001b[0m\u001b[0mucb\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mUCB\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m      6\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[1;33m.\u001b[0m\u001b[0mei\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mEI\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      7\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[1;33m.\u001b[0m\u001b[0muei\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mUEI\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32m~\\PhD\\Code\\Paper\\2019_NeurIPS\\core\\acquisitions\\ucb.py\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m      4\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      5\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mnumpy\u001b[0m \u001b[1;32mas\u001b[0m \u001b[0mnp\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 6\u001b[1;33m \u001b[1;32mfrom\u001b[0m \u001b[1;33m.\u001b[0m\u001b[0macquisition_base\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mAcquisitionBase\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m      7\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      8\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32m~\\PhD\\Code\\Paper\\2019_NeurIPS\\core\\acquisitions\\acquisition_base.py\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m      5\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mnumpy\u001b[0m \u001b[1;32mas\u001b[0m \u001b[0mnp\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      6\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mscipy\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0moptimize\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mminimize\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 7\u001b[1;33m \u001b[1;32mimport\u001b[0m \u001b[0msobol_seq\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m      8\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mtqdm\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mtqdm\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      9\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;31mModuleNotFoundError\u001b[0m: No module named 'sobol_seq'"
     ]
    }
   ],
   "source": [
    "# Copyright (c) 2019\n",
    "# Copyright holder of the paper \"Noisy-Input Entropy Search for Efficient Robust Bayesian Optimization\" submitted to NeurIPS 2019 for review.\n",
    "# All rights reserved.\n",
    "\n",
    "import json\n",
    "from multiprocessing import Process, Queue\n",
    "import queue\n",
    "import numpy as np\n",
    "import pickle\n",
    "import os\n",
    "from scipy.optimize import Bounds\n",
    "import time\n",
    "\n",
    "from core.acquisitions import EI, UCB, UEI\n",
    "from core.acquisitions import NESRejectionSamplingGrid, NESExpProp\n",
    "from core.util import objectives, misc, run_experiments, eval_experiments"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "def load_settings(objective_name):\n",
    "    if objective_name == 'synthetic_1d_01':\n",
    "        objective = objectives.synthetic_1d_01\n",
    "        objective_config = './cfg/param_synth_01_1d.json'\n",
    "    elif objective_name == 'rkhs_1d':\n",
    "        objective = objectives.rkhs_synth\n",
    "        objective_config = './cfg/param_rkhs_1d.json'\n",
    "    elif objective_name == 'gmm_2d':\n",
    "        objective = objectives.gmm_2d\n",
    "        objective_config = './cfg/param_gmm_2d.json'\n",
    "    elif objective_name == 'poly_2d':\n",
    "        objective = objectives.synth_poly_2d_norm\n",
    "        objective_config = './cfg/param_poly_2d.json'\n",
    "    elif objective_name == 'hartmann_3d':\n",
    "        objective = objectives.hartmann_3d\n",
    "        objective_config = './cfg/param_hartmann_3d.json'\n",
    "    elif objective_name == 'rocket_sim':\n",
    "        objective = objectives.rocket_simulation\n",
    "        objective_config = './cfg/param_rocket_sim.json'\n",
    "    else:\n",
    "        raise ValueError(\"Objective does not exist. Please choose an existing one.\")\n",
    "\n",
    "    with open(objective_config) as f:\n",
    "        param_obj = json.load(f)\n",
    "\n",
    "    with open('cfg/exp_params_{}d.json'.format(param_obj['input_dim'])) as f:\n",
    "        param_exp = json.load(f)\n",
    "    param = {**param_exp, **param_obj}\n",
    "\n",
    "    return objective, param"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "def run_all_experiments(experiments_queue, param, objective, res_dir):\n",
    "    while True:\n",
    "        try:\n",
    "            run_idx = experiments_queue.get_nowait()\n",
    "        except queue.Empty:\n",
    "            break\n",
    "        else:\n",
    "            domain = Bounds(np.array(param['lower_bound']), np.array(param['upper_bound']))\n",
    "            print(\"Number of experiments in queue: {} / {}\".format(experiments_queue.qsize() + 1, param['n_runs']))\n",
    "\n",
    "            # Setup acquisition functions\n",
    "            acq_nes_grid = NESRejectionSamplingGrid(\n",
    "                domain=domain, filter_width=np.sqrt(param['input_var']),\n",
    "                n_max_value_samples=param['n_max_value_samples'],\n",
    "                n_function_samples=param['n_rejection_samples'], dx_grid=param['dx'])\n",
    "\n",
    "            acq_nes_ep = NESExpProp(\n",
    "                domain=domain, filter_width=np.sqrt(param['input_var']),\n",
    "                n_max_value_samples=param['n_max_value_samples'])\n",
    "\n",
    "            acq_ucb = UCB(domain=domain)\n",
    "            acq_ei = EI(domain=domain)\n",
    "            acq_uei = UEI(domain=domain, input_var=param['input_var'])\n",
    "\n",
    "            np.random.seed(int(time.time()) + run_idx)  # Important for multiprocessing\n",
    "            x_init = np.random.uniform(domain.lb, domain.ub, (param['n_init'], param['input_dim']))\n",
    "            y_init = objective(x_init, param['noise_var'])\n",
    "\n",
    "            hyper_opt = False  # False for synthetic problems, True for gravity assist maneuver.\n",
    "            run_experiments.run_bo_nes(acq_nes_grid, objective, param, x_init, y_init, run_idx, res_dir)\n",
    "            run_experiments.run_bo_nes(acq_nes_ep, objective, param, x_init, y_init, run_idx, res_dir)\n",
    "            run_experiments.run_bo_uu(acq_ei, objective, param, x_init, y_init, run_idx, res_dir)\n",
    "            run_experiments.run_bo_uu(acq_ucb, objective, param, x_init, y_init, run_idx, res_dir)\n",
    "            run_experiments.run_bo_unsc(acq_uei, objective, param, x_init, y_init, run_idx, res_dir)\n",
    "            run_experiments.run_bo_vanilla(acq_ei, objective, param, x_init, y_init, run_idx, res_dir)\n",
    "            run_experiments.run_bo_pseudo(acq_ei, objective, param, x_init, y_init, run_idx, res_dir)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "def main(objective_name):\n",
    "    # Load Settings\n",
    "    objective, param = load_settings(objective_name)\n",
    "    res_dir = misc.create_results_dir(objective_name)\n",
    "    pickle.dump(param, open(res_dir + \"param.pkl\", \"wb\"))\n",
    "\n",
    "    # Get maximum number of available cores\n",
    "    number_of_processes = os.cpu_count()\n",
    "\n",
    "    # Fill queue with experiment IDs\n",
    "    experiments_queue = Queue()\n",
    "    for i in range(param['n_runs']):\n",
    "        experiments_queue.put(i)\n",
    "\n",
    "    # Spawn processes and work of all experiments in the queue\n",
    "    processes = []\n",
    "    for w in range(number_of_processes):\n",
    "        p = Process(target=run_all_experiments,\n",
    "                    args=(experiments_queue, param, objective, res_dir))\n",
    "        processes.append(p)\n",
    "        p.start()\n",
    "\n",
    "    # Wait for everyone to be finished\n",
    "    for p in processes:\n",
    "        p.join()\n",
    "        \n",
    "    return res_dir, objective"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Created: Results/synthetic_1d_01/2019-05-23_16-40/\n",
      "Elements in queue: 10 / 10\n",
      "Elements in queue: 9 / 10\n",
      "Elements in queue: 8 / 10\n",
      "Elements in queue: 7 / 10\n",
      "Elements in queue: 6 / 10\n",
      "Elements in queue: 5 / 10\n",
      "Elements in queue: 4 / 10\n",
      "Elements in queue: 3 / 10\n"
     ]
    }
   ],
   "source": [
    "if __name__ == '__main__':\n",
    "    res_dir, objective = main('synthetic_1d_01')\n",
    "    eval_experiments.plot_convergence(res_dir, objective)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
